import json
import random
import re
import threading
import time
from datetime import datetime
import uuid

import requests
import os
import base64
import logging
import pandas as pd
import numpy as np
from django.core.management import call_command
from django.shortcuts import render

from django_filters.rest_framework import FilterSet
from rest_framework import viewsets
from sklearn.metrics.pairwise import cosine_similarity
from langchain.agents import tool, initialize_agent, Tool, AgentType
from langchain_community.llms.tongyi import Tongyi
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

from CowProject.settings import comment_col
from users.models import HouseListing, School, HouseTransaction
from rest_framework import status
from django.contrib.auth import get_user_model

from utils.athenticate import MyAuthentication
from django.conf import settings
from django.http import HttpResponse, JsonResponse
from rest_framework.generics import ListAPIView
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.decorators import permission_classes
from rest_framework.permissions import IsAuthenticated
from CowProject import settings
from users.models import User, UserProfile, RealNameAuth, HouseType, HouseListing, HouseView
from users.sers import HouseListingSerializers, HouserTypeSerializers, HouseTransactionSerializer
from users.models import User, UserProfile, RealNameAuth, HouseType, HouseListing, HouseView, Contract, RentContract, SellContract
from users.sers import (HouseListingSerializers, HouserTypeSerializers, ContractSerializer,
                       RentContractSerializer, SellContractSerializer, ContractCreateSerializer)
from utils.image_code import random_code, make_varify_image
from utils.myredis import r
from utils.sms import sm
from utils.myjwt import myjwt
from qiniu import Auth


User = get_user_model()
logger = logging.getLogger(__name__)


# Create your views here.
class ImageCodeCheckView(APIView):
    def get(self, request):
        try:
            # 获取uuid
            uuid = request.query_params.get("uuid")
            if not uuid:
                return Response({"code": 400, "msg": "缺少uuid参数"}, status=400)

            # 生成四位的随机验证码
            code_str = random_code(4)
            if not code_str:
                return Response({"code": 500, "msg": "生成验证码失败"}, status=500)

            # 存入redis
            try:
                r.set_value_time(uuid, code_str, 60)
            except Exception as e:
                logger.error(f"Redis存储验证码失败: {str(e)}")
                return Response({"code": 500, "msg": "存储验证码失败"}, status=500)

            # 生成图片流
            image = make_varify_image(code_str)
            if not image:
                return Response({"code": 500, "msg": "生成验证码图片失败"}, status=500)

            response = HttpResponse(image, content_type="image/jpeg")
            response["Cache-Control"] = "no-cache, no-store, must-revalidate"
            response["Pragma"] = "no-cache"
            response["Expires"] = "0"
            return response
        except Exception as e:
            logger.error(f"验证码生成过程失败: {str(e)}")
            return Response({"code": 500, "msg": "生成验证码失败"}, status=500)


class Send_Message(APIView):
    def post(self, request):
        data = request.data
        phone = data["phone"]
        imagecode = data.get("imagecode")
        uuid = data.get("uuid")
        result = re.match(r"^1[3-9]\d{9}$", phone)
        if not result:
            return Response({"code": 500, "msg": "手机号格式错误"})
        value = r.get_value(uuid).decode("utf-8")
        if value.lower() != imagecode.lower():
            return Response({"code": 500, "msg": "验证码错误"})
        else:
            r.delete_value(uuid)
        smscode = r.get_value(phone)
        if smscode is None:
            code = random.randint(1000, 9999)
            flag = sm.send_message(phone, code)
            if flag:
                r.set_value_time(phone, code, 180)
            return Response({"code": 200, "msg": "验证码发送成功"})
        else:
            return Response({"code": 500, "msg": "验证码已发送，请稍一分钟后再试"})


# 登录
class Code_Login(APIView):
    def post(self, request):
        data = request.data
        phone = data['phone']
        code = data['code']
        # 获取用手机号、短信验证码、正则格式验证
        result = re.match(r'^1[3-9]\d{9}$', phone)
        if result is None:
            return Response({"code": 500, "msg": "手机号格式错误"})
        # 通过手机号查询redis，是否存在，如果存在验证验证码
        value = r.get_value(phone)
        if not value:
            return Response({"code": 500, "msg": "验证码已过期"})
        value = value.decode('utf-8')
        if value.lower() != code.lower():
            return Response({"code": 500, "msg": "验证码错误"})
        # 查询mysql数据库，如果存在返回用户信息，用用户信息生成jwt token返回
        try:
            users = User.objects.get(phone=phone)
        except User.DoesNotExist:
            users = User.objects.create(
                username=phone,
                phone=phone,
                password=code
            )

        # 生成token
        payload = {
            "userid": users.id,
            'username': users.phone,
            'exp': int(time.time()) + 3600
        }
        token = myjwt.encode(payload)
        if not token:
            return Response({"code": 500, "msg": "生成token失败"})

        # 生成refresh token
        refresh_payload = {
            "userid": users.id,
            'username': users.phone,
            'exp': int(time.time()) + 7200
        }
        retoken = myjwt.encode(refresh_payload)
        if not retoken:
            return Response({"code":500, "msg": "生成refresh token失败"})
            
        return Response({
            "code": 200,
            "userid": users.id,
            "token": token,
            "retoken": retoken
        })


class password_Login(APIView):
    #手机号密码登录""
    def post(self,request):
        data = request.data
        phone = data.get('phone')
        password = data.get('password')
        try:
            user = User.objects.get(phone=phone)
        except User.DoesNotExist:
            return Response({"code": 500, "msg": "用户不存在"})
            
        if user.password == password:
            # 生成token
            payload = {
                "userid": user.id,
                'username': user.phone,
                'exp': int(time.time()) + 3600
            }
            token = myjwt.encode(payload)
            if not token:
                return Response({"code":500, "msg": "生成token失败"})
                
            # 生成refresh token
            refresh_payload = {
                "userid": user.id,
                'username': user.phone,
                'exp': int(time.time()) + 7200
            }
            retoken = myjwt.encode(refresh_payload)
            if not retoken:
                return Response({"code":500, "msg": "生成refresh token失败"})
                
            return Response({
                "code": 200,
                "userid": user.id,
                "token": token,
                "retoken": retoken
            })
        else:
            return Response({"code": 500, "msg": "密码错误"})


class Register(APIView):
    def post(self, request):
        data = request.data
        phone = data['phone']
        password = data.get('password')
        code = data.get('code')
        result = re.match(r'^1[3-9]\d{9}$', phone)
        if result is None:
            return Response({"code": 500, "msg": "手机号格式错误"})
        value = r.get_value(phone).decode('utf-8')
        if value is None:
            return Response({"code": 500, "msg": "验证码已过期"})
        if value.lower() != code.lower():
            return Response({"code": 500, "msg": "验证码错误"})
        try:
            User.objects.get(phone=phone)  # 存在则进入 try 块
            return Response({"code": 500, "msg": "用户已存在"})
        except User.DoesNotExist:  # 不存在则进入 except 块
            # 创建用户（注意：Django 密码需加密，此处简化）
            User.objects.create(
                username=phone,
                password=password,
                phone=phone,
            )
            return Response({"code": 200, "msg": "注册成功"})


class DingTalkLogin(APIView):
    """钉钉登录处理"""

    def get(self, request):
        """处理钉钉回调"""
        try:
            # 获取钉钉回调的授权码
            code = request.query_params.get('code')
            print(code)
            if not code:
                return Response({"code": 500, "msg": "没有收到钉钉的授权码"})

            # 第一步：获取用户访问令牌
            token_resp = requests.post(
                'https://api.dingtalk.com/v1.0/oauth2/userAccessToken',
                json={
                    "clientId": "dingtvk3mg5whlxuhdim",  # 你的钉钉应用 clientId
                    "clientSecret": "boMviNgNxn9dqct8Uh4uigbxKgEApTz3fCGKLu3MBGWeNSI87xdZY1_JaeJAB5EO",  # 你的钉钉应用密钥
                    "code": code,
                    "grantType": "authorization_code"
                }
            ).json()

            if 'accessToken' not in token_resp:
                return Response({"code": 500, "msg": "获取钉钉访问令牌失败"})

            # 第二步：获取用户信息
            user_resp = requests.get(
                'https://api.dingtalk.com/v1.0/contact/users/me',
                headers={"x-acs-dingtalk-access-token": token_resp['accessToken']}
            ).json()

            # 获取用户手机号
            phone = user_resp.get('mobile')
            if not phone:
                return Response({"code": 500, "msg": "无法获取钉钉用户手机号"})

            # 第三步：查找或创建用户
            try:
                user = User.objects.get(phone=phone)
                print(user)
            except User.DoesNotExist:
                # 如果用户不存在，创建新用户
                username = user_resp.get('nick', phone)  # 优先使用钉钉昵称，没有则用手机号
                user = User.objects.create(
                    username=username,
                    phone=phone,
                    password=phone  # 这里可以生成随机密码
                )

            # 第四步：生成JWT令牌
            token = myjwt.encode({
                "userid": user.id,
                'username': user.phone,
                'exp': int(time.time()) + 3600  # 1小时过期
            })

            retoken = myjwt.encode({
                "userid": user.id,
                'username': user.phone,
                'exp': int(time.time()) + 7200  # 2小时过期
            })

            # 返回登录成功信息，重定向到前端并携带参数
            # 注意：这里不需要添加Bearer前缀，因为前端会处理
            redirect_url = f"http://localhost:5173/login?token={token}&userid={user.id}&retoken={retoken}"
            return HttpResponse(f'<script>window.location.href = "{redirect_url}";</script>')

        except Exception as e:
            print(f"DingTalk login error: {str(e)}")  # 添加错误日志
            return Response({
                "code": 500,
                "msg": f"钉钉登录过程出错: {str(e)}"
            })


# 刷新token
class ReToken(APIView):
    def post(self, request):
        data = request.data
        retoken = data['retoken']
        userdata = myjwt.decode(retoken)
        token = myjwt.encode({"userid": 1, 'name': 'sdf', 'exp': int(time.time()) + 3600})
        retoken = myjwt.encode({"userid": 1, 'name': 'sdf', 'exp': int(time.time()) + 7200})
        return Response({"code": 200, 'userid': 1, 'token': token, 'retoke': retoken})


# 退出登录
class Logout(APIView):
    def post(self, request):
        try:
            auth_header = request.headers.get("Authorization")
            print(f"Received Authorization header: {auth_header}")  # 调试日志

            if not auth_header:
                return Response({"code": 409, "msg": "缺少token"})

            parts = auth_header.split()
            if len(parts) != 2 or parts[0].lower() != "bearer":
                print(f"Invalid Authorization header format: {auth_header}")  # 调试日志
                return Response({"code": 409, "msg": "token格式错误"})

            token = parts[1]
            print(f"Extracted token: {token}")  # 调试日志

            # 检查token是否已在黑名单中 - 使用get_value
            if r.get_value(token):
                print(f"Token found in blacklist: {token}")  # 调试日志
                return Response({"code": 409, "msg": "token已失效"})

            # 解码token
            data = myjwt.decode(token)
            if not data:
                print(f"Failed to decode token: {token}")  # 调试日志
                return Response({"code": 409, "msg": "token无效或已过期"})

            print(f"Successfully decoded token data: {data}")  # 调试日志

            # 获取过期时间并加入黑名单
            exp = data.get('exp', int(time.time()) + 3600)  # 默认1小时后过期
            remaining_time = max(1, exp - int(time.time()))  # 确保至少有1秒的有效期

            print(f"Adding token to blacklist with expiry: {exp}")  # 调试日志
            # 使用set_value_time
            r.set_value_time(token, "blacklisted", remaining_time)

            return Response({"code": 200, "msg": "退出成功"})

        except Exception as e:
            print(f"Logout error: {str(e)}")  # 调试日志
            return Response({"code": 409, "msg": f"退出失败: {str(e)}"})


# 获取用户信息
class UserInfo(APIView):
    def get(self, request):
        try:
            # 从请求头获取token
            auth_header = request.headers.get("Authorization")
            if not auth_header:
                return Response({"code": 409, "msg": "缺少token"})

            parts = auth_header.split()
            if len(parts) != 2 or parts[0].lower() != "bearer":
                return Response({"code": 409, "msg": "token格式错误"})

            token = parts[1]

            # 解码token
            data = myjwt.decode(token)
            if not data:
                return Response({"code": 409, "msg": "token无效或已过期"})

            # 获取用户信息
            try:
                user = User.objects.get(id=data['userid'])
                # 获取用户详情信息
                try:
                    user_profile = UserProfile.objects.get(user=user)
                    avatar_url = user_profile.avatar_url
                    is_verified = user_profile.is_verified
                except UserProfile.DoesNotExist:
                    avatar_url = None
                    is_verified = False

                return Response({
                    "code": 200,
                    "data": {
                        "username": user.username,
                        "phone": user.phone,
                        "avatar_url": avatar_url,
                        "is_verified": is_verified
                    }
                })
            except User.DoesNotExist:
                return Response({"code": 500, "msg": "用户不存在"})

        except Exception as e:
            print(f"Get user info error: {str(e)}")
            return Response({"code": 500, "msg": "获取用户信息失败"})


class QiniuTokenView(APIView):
    """获取七牛云上传token的接口"""

    @permission_classes([IsAuthenticated])
    def get(self, request):
        try:
            # 需要填写你的 Access Key 和 Secret Key
            access_key = 'zMV57ldZnWGy7gVI5sbjBONW62fS7hOaXtkND345'
            secret_key = 'xfM-N6uSKSwnMfqSmUkK_FLUvUSdOqaE5EvLJuT3'

            # 构建鉴权对象
            q = Auth(access_key, secret_key)

            # 要上传的空间
            bucket_name = 'h2412aowei'

            # 生成上传token，3600为token过期时间，秒为单位
            token = q.upload_token(bucket_name, None, 3600)

            return Response({
                'code': 200,
                'msg': '获取token成功',
                'data': {
                    'token': token,
                    'domain': 'http(s)://upload-z1.qiniup.com'  # 这里填写你的七牛云域名
                }
            })
        except Exception as e:
            return Response({
                'code': 500,
                'msg': f'获取token失败: {str(e)}'
            })


class UpdateProfileView(APIView):
    def post(self, request):
        try:
            # 获取并验证token
            auth_header = request.headers.get("Authorization")
            if not auth_header:
                return Response({"code": 409, "msg": "缺少token"})

            parts = auth_header.split()
            if len(parts) != 2 or parts[0].lower() != "bearer":
                return Response({"code": 409, "msg": "token格式错误"})

            token = parts[1]

            # 解码token
            data = myjwt.decode(token)
            if not data:
                return Response({"code": 409, "msg": "token无效或已过期"})

            # 获取用户
            try:
                user = User.objects.get(id=data['userid'])
            except User.DoesNotExist:
                return Response({"code": 404, "msg": "用户不存在"})

            # 获取上传的文件
            avatar = request.FILES.get('avatar')
            if not avatar:
                return Response({"code": 400, "msg": "没有收到文件"})

            # 验证文件类型
            allowed_types = ['image/jpeg', 'image/png', 'image/gif']
            if avatar.content_type not in allowed_types:
                return Response({"code": 400, "msg": "只支持 JPG、PNG、GIF 格式的图片"})

            # 创建保存目录
            upload_dir = os.path.join(settings.MEDIA_ROOT, 'avatars')
            if not os.path.exists(upload_dir):
                os.makedirs(upload_dir)

            # 生成文件名
            file_extension = os.path.splitext(avatar.name)[1]
            filename = f"avatar_{user.id}{file_extension}"
            filepath = os.path.join(upload_dir, filename)

            # 保存文件
            with open(filepath, 'wb+') as destination:
                for chunk in avatar.chunks():
                    destination.write(chunk)

            # 生成访问URL
            avatar_url = f"/media/avatars/{filename}"

            # 更新用户详情
            user_profile, created = UserProfile.objects.get_or_create(
                user=user,
                defaults={
                    'user_type': 'tenant',
                    'status': True
                }
            )
            user_profile.avatar_url = avatar_url
            user_profile.save()

            return Response({
                "code": 200,
                "msg": "更新成功",
                "data": {
                    "avatar_url": avatar_url
                }
            })

        except Exception as e:
            print(f"Update profile error: {str(e)}")
            return Response({
                "code": 500,
                "msg": f"更新失败: {str(e)}"
            })


class IDCardRecognitionView(APIView):
    """身份证识别接口"""

    @permission_classes([IsAuthenticated])
    def post(self, request):
        try:
            # Baidu OCR API credentials
            API_KEY = "1wEYuhJfgZzhSKRZnpjDimSB"
            SECRET_KEY = "Vzv1lRGXhiSNq9fvRVUUFA4azUSdOqaE5EvLJuT3"

            # Get the image URL from request
            image_url = request.data.get('image_url')
            if not image_url:
                return Response({"code": 400, "msg": "图片URL不能为空"})

            # Download image from Qiniu with increased timeout and retries
            session = requests.Session()
            adapter = requests.adapters.HTTPAdapter(max_retries=3)
            session.mount('http://', adapter)
            session.mount('https://', adapter)

            try:
                # 禁用SSL验证，但在生产环境中不建议这样做
                image_response = session.get(image_url, timeout=30, verify=False)
                if image_response.status_code != 200:
                    return Response({"code": 400, "msg": f"无法下载图片，状态码：{image_response.status_code}"})
            except requests.exceptions.RequestException as e:
                return Response({"code": 400, "msg": f"下载图片失败：{str(e)}"})

            # 打印调试信息
            print(f"Downloaded image size: {len(image_response.content)} bytes")

            image_base64 = base64.b64encode(image_response.content).decode()

            # Get Baidu access token
            def get_access_token():
                url = "https://aip.baidubce.com/oauth/2.0/token"
                params = {
                    "grant_type": "client_credentials",
                    "client_id": API_KEY,
                    "client_secret": SECRET_KEY
                }
                try:
                    response = session.post(url, params=params, timeout=30, verify=True)  # 百度API需要保持SSL验证
                    if response.status_code != 200:
                        raise Exception(f"获取百度access_token失败，状态码：{response.status_code}")
                    return response.json().get("access_token")
                except requests.exceptions.RequestException as e:
                    raise Exception(f"获取百度access_token失败：{str(e)}")

            # Call Baidu OCR API
            access_token = get_access_token()
            ocr_url = f"https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token={access_token}"

            payload = {
                'image': image_base64,
                'id_card_side': 'front',
                'detect_risk': 'false',
                'detect_quality': 'false',
                'detect_photo': 'false'
            }

            headers = {
                'Content-Type': 'application/x-www-form-urlencoded',
                'Accept': 'application/json'
            }

            try:
                response = session.post(ocr_url, data=payload, headers=headers, timeout=30,
                                        verify=True)  # 百度API需要保持SSL验证
                if response.status_code != 200:
                    return Response({
                        "code": 500,
                        "msg": f"百度OCR服务调用失败: {response.text}"
                    })
            except requests.exceptions.RequestException as e:
                return Response({
                    "code": 500,
                    "msg": f"调用百度OCR服务失败：{str(e)}"
                })

            ocr_result = response.json()

            # 检查OCR结果是否包含错误信息
            if 'error_code' in ocr_result:
                return Response({
                    "code": 500,
                    "msg": f"识别失败: {ocr_result.get('error_msg', '未知错误')}"
                })

            return Response({
                "code": 200,
                "msg": "识别成功",
                "data": ocr_result
            })

        except Exception as e:
            print(f"ID card recognition error: {str(e)}")
            return Response({
                "code": 500,
                "msg": f"识别失败: {str(e)}"
            })


class RealNameAuthView(APIView):
    """实名认证接口"""

    @permission_classes([IsAuthenticated])
    def post(self, request):
        try:
            # 从请求头获取token
            auth_header = request.headers.get("Authorization")
            if not auth_header:
                return Response({"code": 409, "msg": "缺少token"})

            parts = auth_header.split()
            if len(parts) != 2 or parts[0].lower() != "bearer":
                return Response({"code": 409, "msg": "token格式错误"})

            token = parts[1]

            # 解码token
            data = myjwt.decode(token)
            if not data:
                return Response({"code": 409, "msg": "token无效或已过期"})

            # 获取用户信息
            try:
                user = User.objects.get(id=data['userid'])
            except User.DoesNotExist:
                return Response({"code": 404, "msg": "用户不存在"})

            # 获取请求数据
            data = request.data
            real_name = data.get('real_name')
            id_card = data.get('id_card')
            id_card_front = data.get('id_card_front')

            # 验证必要字段
            if not all([real_name, id_card, id_card_front]):
                return Response({
                    "code": 400,
                    "msg": "缺少必要字段"
                })

            # 验证身份证号格式
            if not re.match(r'^\d{17}[\dXx]$', id_card):
                return Response({
                    "code": 400,
                    "msg": "身份证号格式错误"
                })

            # 检查是否已经实名认证
            try:
                auth = RealNameAuth.objects.get(user=user)
                if auth.auth_status == 'approved':
                    return Response({
                        "code": 400,
                        "msg": "您已完成实名认证"
                    })
                # 更新现有记录
                auth.real_name = real_name
                auth.id_card = id_card
                auth.id_card_front = id_card_front
                auth.auth_status = 'pending'
                auth.save()
            except RealNameAuth.DoesNotExist:
                # 创建新的实名认证记录
                RealNameAuth.objects.create(
                    user=user,
                    real_name=real_name,
                    id_card=id_card,
                    id_card_front=id_card_front,
                    auth_status='pending'
                )

            # 更新用户详情表中的实名认证信息
            try:
                profile = UserProfile.objects.get(user=user)
                profile.real_name = real_name
                profile.id_card = id_card
                profile.is_verified = True
                profile.save()
            except UserProfile.DoesNotExist:
                UserProfile.objects.create(
                    user=user,
                    real_name=real_name,
                    id_card=id_card,
                    is_verified=True
                )

            return Response({
                "code": 200,
                "msg": "实名认证信息提交成功"
            })

        except Exception as e:
            print(f"Real name auth error: {str(e)}")
            return Response({
                "code": 500,
                "msg": f"实名认证失败: {str(e)}"
            })


class Filter(FilterSet):
    class Meta:
        model = HouseListing
        fields = ['type']


class HouseListingAPI(ListAPIView):
    """房源列表API"""
    queryset = HouseListing.objects.filter(is_delete=False)
    serializer_class = HouseListingSerializers
    filterset_class = Filter


class HouseDetailAPI(APIView):
    """房源详情API"""

    def get(self, request):
        try:
            id = request.GET.get('id')
            if not id:
                return Response({"code": 400, "msg": "房源ID不能为空"})

            try:
                house = HouseListing.objects.get(pk=id, is_delete=False)
            except HouseListing.DoesNotExist:
                return Response({"code": 404, "msg": "房源不存在"})

            # 获取token并尝试解析用户信息
            auth_header = request.headers.get("Authorization")
            if auth_header:
                try:
                    parts = auth_header.split()
                    if len(parts) == 2 and parts[0].lower() == "bearer":
                        token = parts[1]
                        data = myjwt.decode(token)
                        if data:
                            user_id = data.get('userid')
                            try:
                                user = User.objects.get(id=user_id)
                                # 创建浏览记录
                                HouseView.objects.get_or_create(
                                    user=user,
                                    house=house,
                                )
                                # 更新浏览次数
                                house.views_count = house.views_count + 1
                                house.save()
                            except User.DoesNotExist:
                                pass
                except Exception as e:
                    logger.error(f"Token decode error: {str(e)}")

            serializer = HouseListingSerializers(house)
            return Response({
                "code": 200,
                "msg": "获取房源详情成功",
                "data": serializer.data
            })

        except Exception as e:
            logger.error(f"Get house detail error: {str(e)}")
            return Response({
                "code": 500,
                "msg": f"获取房源详情失败: {str(e)}"
            })


class HouseTypeAPI(APIView):
    """房源类型API"""

    def get(self, request):
        house_types = HouseType.objects.all()
        serializer = HouserTypeSerializers(house_types, many=True)
        return Response(serializer.data)


class HouseRecommendAPI(APIView):
    """AI房源推荐API"""

    def get(self, request):
        try:
            limit = int(request.GET.get('limit', 10))

            # 获取token并尝试解析用户信息
            auth_header = request.headers.get("Authorization")
            user_id = None

            if auth_header:
                try:
                    parts = auth_header.split()
                    if len(parts) == 2 and parts[0].lower() == "bearer":
                        token = parts[1]
                        data = myjwt.decode(token)
                        if data:
                            user_id = data.get('userid')
                except Exception as e:
                    print(f"Token decode error: {str(e)}")

            if user_id:
                # 已登录用户：获取个性化推荐
                viewed_houses = HouseView.objects.filter(
                    user_id=user_id,
                    is_delete=False
                ).values_list('house_id', flat=True)

                if viewed_houses.exists():
                    recommended_houses = HouseListing.objects.filter(
                        houseview__user_id__in=HouseView.objects.filter(
                            house_id__in=viewed_houses
                        ).exclude(
                            user_id=user_id
                        ).values_list('user_id', flat=True).distinct(),
                        is_delete=False,
                        status='available'
                    ).exclude(
                        id__in=viewed_houses
                    ).distinct()

                    if recommended_houses.count() < limit:
                        popular_houses = HouseListing.objects.filter(
                            is_delete=False,
                            status='available'
                        ).exclude(
                            id__in=list(viewed_houses) + list(recommended_houses.values_list('id', flat=True))
                        ).order_by('-views_count')[:limit - recommended_houses.count()]

                        recommended_houses = list(recommended_houses) + list(popular_houses)
                else:
                    # 无浏览历史：返回热门房源
                    recommended_houses = HouseListing.objects.filter(
                        is_delete=False,
                        status='available'
                    ).order_by('-views_count')[:limit]
            else:
                # 未登录用户：返回热门房源
                recommended_houses = HouseListing.objects.filter(
                    is_delete=False,
                    status='available'
                ).order_by('-views_count')[:limit]

            # 序列化数据
            serializer = HouseListingSerializers(recommended_houses, many=True)

            return Response({
                "code": 200,
                "msg": "获取推荐房源成功",
                "data": serializer.data
            })

        except Exception as e:
            logger.error(f"House recommendation error: {str(e)}")
            return Response({
                "code": 500,
                "msg": f"获取推荐房源失败: {str(e)}"
            })

    def post(self, request):
        """记录用户浏览行为"""
        try:
            # 检查用户是否登录
            auth_header = request.headers.get("Authorization")
            if not auth_header:
                return Response({
                    "code": 409,
                    "msg": "需要登录才能记录浏览行为"
                })

            parts = auth_header.split()
            if len(parts) != 2 or parts[0].lower() != "bearer":
                return Response({
                    "code": 409,
                    "msg": "token格式错误"
                })

            token = parts[1]
            data = myjwt.decode(token)
            if not data:
                return Response({
                    "code": 409,
                    "msg": "token无效或已过期"
                })

            house_id = request.data.get('house_id')
            if not house_id:
                return Response({
                    "code": 400,
                    "msg": "房源ID不能为空"
                })

            try:
                user = User.objects.get(id=data['userid'])
                house = HouseListing.objects.get(id=house_id, is_delete=False)
            except User.DoesNotExist:
                return Response({
                    "code": 404,
                    "msg": "用户不存在"
                })
            except HouseListing.DoesNotExist:
                return Response({
                    "code": 404,
                    "msg": "房源不存在"
                })

            # 创建或更新浏览记录
            HouseView.objects.get_or_create(
                user=user,
                house=house
            )

            # 更新浏览次数
            house.views_count = house.views_count + 1
            house.save()

            return Response({
                "code": 200,
                "msg": "浏览记录保存成功"
            })

        except Exception as e:
            logger.error(f"Record house view error: {str(e)}")
            return Response({
                "code": 500,
                "msg": f"保存浏览记录失败: {str(e)}"
            })


from elasticsearch import Elasticsearch

es = Elasticsearch("http://120.55.127.214:9200")


# class SearchData(APIView):
#     def post(self, request):
#         # 数据同步
#         news = School.objects.all()
#         for i in news:
#             es.index(index='school', body={
#                 'id': i.id,
#                 'table_name': 'school',
#                 'name': i.name,
#                 'type': i.school_type,
#                 'address': i.address,
#             })
#         return Response({
#             "code": 200,
#             "msg": "同步成功"
#         })
#
#     def get(self, request):
#         title = request.GET.get('title')
#         dsl = {
#             "query": {
#                 "match": {"name": title},
#
#             }
#         }
#         res = es.search(index="school", body=dsl)
#         return Response({
#             "code": 200,
#             "msg": "查询成功",
#             "data":  res['hits']['hits']
#         })


from elasticsearch import Elasticsearch
# from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
# from rest_framework.response import Response
from .models import HouseListing

es = Elasticsearch("http://47.97.6.191:9200/")


class SearchData(APIView):
    def post(self, request):
        """将房源数据同步到Elasticsearch"""
        houses = HouseListing.objects.all()

        # 批量同步数据到ES
        for house in houses:
            es.index(
                index='house_listing',
                id=house.id,
                body={
                    'id': house.id,
                    'table_name': 'house_listing',
                    'title': house.title,
                    'description': house.description,
                    'address': house.address,
                    'city': house.city,
                    'district': house.district,
                    'room_count': house.room_count,
                    'price': float(house.price),
                    'area': float(house.area),
                    'status': house.status,
                    'orientation': house.get_orientation_display(),
                    'decoration_type': house.get_decoration_type_display(),
                    'images': house.images
                }
            )

        return Response({
            "code": 200,
            "msg": "房源数据同步成功"
        })

    def get(self, request):
        """多字段搜索房源"""
        # 获取搜索参数
        title = request.GET.get('title')
        description = request.GET.get('description')
        address = request.GET.get('address')
        city = request.GET.get('city')
        district = request.GET.get('district')

        # 构建查询DSL
        must_clauses = []

        if title:
            must_clauses.append({"match": {"title": title}})
        if description:
            must_clauses.append({"match": {"description": description}})
        if address:
            must_clauses.append({"match": {"address": address}})
        if city:
            must_clauses.append({"match": {"city": city}})
        if district:
            must_clauses.append({"match": {"district": district}})

        # 如果没有任何搜索参数，返回所有房源
        if not must_clauses:
            query = {"match_all": {}}
        else:
            query = {"bool": {"must": must_clauses}}

        dsl = {
            "query": query,
            "highlight": {
                "fields": {
                    "title": {},
                    "description": {},
                    "address": {}
                },
                "pre_tags": ["<em class='highlight'>"],
                "post_tags": ["</em>"]
            }
        }

        # 执行搜索
        res = es.search(index="house_listing", body=dsl)

        # 处理搜索结果
        results = []
        for hit in res['hits']['hits']:
            source = hit['_source']

            # 如果有高亮结果，替换原始字段
            if 'highlight' in hit:
                for field in hit['highlight']:
                    source[field] = hit['highlight'][field][0]

            results.append({
                '_id': hit['_id'],
                '_score': hit['_score'],
                '_source': source
            })

        return Response({
            "code": 200,
            "msg": "查询成功",
            "total": res['hits']['total']['value'],
            "data": results
        })


from drf_haystack.viewsets import HaystackViewSet
from .indexser import HouseListingIndexSerializer
class HouseListingSearchViewSet(HaystackViewSet):
    index_models = [HouseListing]
    serializer_class = HouseListingIndexSerializer

    def list(self, request, *args, **kwargs):
        # 先执行搜索获取结果
        response = super().list(request, *args, **kwargs)

        # 在后台线程中执行索引重建
        def rebuild_index():
            # 延迟5秒执行，确保搜索响应已返回
            time.sleep(5)

            try:
                print("开始重建搜索索引...")

                # 删除现有索引
                call_command('clear_index', interactive=False, verbosity=0)
                print("索引已删除")

                # 创建新索引
                call_command('update_index', verbosity=0)
                print("新索引已创建")

                # 优化索引
                call_command('rebuild_index', interactive=False, verbosity=0)
                print("索引重建完成")

            except Exception as e:
                print(f"索引重建失败: {str(e)}")

        # 启动后台线程执行索引重建
        threading.Thread(target=rebuild_index, daemon=True).start()

        return response
from .models import Cart

class AddCartView(APIView):
    authentication_classes = [MyAuthentication]

    def post(self, request):
        user_id = request.data.get('user')
        house_id = request.data.get('house')

        if not user_id or not house_id:
            return Response({"msg": "参数错误"}, status=400)

        try:
            user = User.objects.get(id=user_id)
            house = HouseListing.objects.get(id=house_id)
        except (User.DoesNotExist, HouseListing.DoesNotExist):
            return Response({"msg": "用户或房源不存在"}, status=404)

        # 检查是否已加入收藏列表
        if Cart.objects.filter(user=user, house=house).exists():
            return Response({"msg": "该房源已在收藏列表中"})

        # 添加到购物车
        Cart.objects.create(user=user, house=house)
        return Response({"msg": "添加成功"})


class CartView(APIView):
    authentication_classes = [MyAuthentication]

    def get(self, request):
        user_id = request.GET.get('user')

        if not user_id:
            return Response({"msg": "参数错误：缺少用户ID"}, status=400)

        try:
            user_id = int(user_id)
        except ValueError:
            return Response({"msg": "参数错误：user 必须是一个数字"}, status=400)

        try:
            user = User.objects.get(id=user_id)
        except User.DoesNotExist:
            return Response({"msg": "用户不存在"}, status=404)

        carts = Cart.objects.filter(user=user)
        houses = [cart.house for cart in carts]

        serializer = HouseListingSerializers(houses, many=True)
        return Response({"msg": "OK", "data": serializer.data})

class CheckCartView(APIView):
    authentication_classes = [MyAuthentication]

    def get(self, request):
        user_id = request.GET.get('user')
        if not user_id:
            return Response({"msg": "用户还未添加收藏"}, status=401)
        try:
            user_id = int(user_id)
        except ValueError:
            return Response({"msg": "参数错误：user 必须是一个数字"}, status=400)
        try:
            user = User.objects.get(id=user_id)
        except User.DoesNotExist:
            return Response({"msg": "用户不存在"}, status=404)
        carts = Cart.objects.filter(user=user)
        houses = [cart.house for cart in carts]
        serializer = HouseListingSerializers(houses, many=True)
        return Response({"msg": "OK", "data": serializer.data})



class ContractCreateView(APIView):
    """
    合同创建接口
    """
    authentication_classes = [MyAuthentication]

    def post(self, request):
        try:
            # 生成合同编号
            current_date = datetime.now().strftime('%Y%m%d')
            random_str = str(uuid.uuid4().hex)[:6]
            contract_number = f"CON{current_date}{random_str}"

            # 将合同编号添加到请求数据中
            data = request.data.copy()
            data['contract_number'] = contract_number

            # 处理文件上传
            contract_file = request.FILES.get('contract_file')
            if contract_file:
                data['contract_file'] = contract_file

            annexes = request.FILES.getlist('annexes')
            if annexes:
                data['annexes'] = annexes

            # 获取房源和房东信息
            try:
                house = HouseListing.objects.get(id=data['house_id'])
                data['landlord_id'] = house.landlord.id
            except HouseListing.DoesNotExist:
                return Response({
                    'code': 404,
                    'msg': '房源不存在'
                }, status=status.HTTP_404_NOT_FOUND)

            # 序列化和验证数据
            serializer = ContractCreateSerializer(data=data)
            if not serializer.is_valid():
                return Response({
                    'code': 400,
                    'msg': '数据验证失败',
                    'errors': serializer.errors
                }, status=status.HTTP_400_BAD_REQUEST)

            validated_data = serializer.validated_data
            contract_type = validated_data['contract_type']

            # 创建基础合同
            contract = Contract.objects.create(
                contract_type=contract_type,
                contract_number=contract_number,
                house_id=validated_data['house_id'],
                landlord_id=house.landlord.id,
                tenant_id=validated_data['tenant_id'],
                total_amount=validated_data['total_amount'],
                deposit=validated_data['deposit'],
                effective_time=validated_data['effective_time'],
                expire_time=validated_data['expire_time'],
                remarks=validated_data.get('remarks', ''),
                contract_file=contract_file if contract_file else None,
                annexes=annexes[0] if annexes else None
            )

            # 根据合同类型创建具体合同
            if contract_type == 'RENT':
                RentContract.objects.create(
                    contract=contract,
                    rent=validated_data['rent'],
                    payment_cycle=validated_data['payment_cycle'],
                    payment_due_day=validated_data['payment_due_day'],
                    start_date=validated_data['effective_time'],
                    end_date=validated_data['expire_time'],
                    grace_period=validated_data.get('grace_period', 3),
                    early_termination_allowed=validated_data.get('early_termination_allowed', True),
                    early_termination_fee=validated_data.get('early_termination_fee', None)
                )
            else:  # SELL
                SellContract.objects.create(
                    contract=contract,
                    house_price=validated_data['house_price'],
                    payment_method=validated_data['payment_method'],
                    down_payment=validated_data['down_payment'],
                    mortgage_bank=validated_data.get('mortgage_bank'),
                    mortgage_amount=validated_data.get('mortgage_amount'),
                    transfer_date=validated_data['transfer_date'],
                    property_handover_date=validated_data['property_handover_date']
                )

            return Response({
                'code': 200,
                'msg': '合同创建成功',
                'data': {
                    'contract_id': contract.id,
                    'contract_number': contract.contract_number
                }
            })

        except Exception as e:
            return Response({
                'code': 500,
                'msg': f'合同创建失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class ContractView(APIView):
    authentication_classes = [MyAuthentication]

    def get(self, request):
        user_id = request.GET.get('user')
        contract_id = request.GET.get('id')

        if not (user_id or contract_id):
            return Response({
                'code': 400,
                'msg': '缺少必要参数 user 或 id'
            }, status=400)

        try:
            if contract_id:
                contract = Contract.objects.filter(id=contract_id).first()
            else:
                user_id = int(user_id)
                contract = Contract.objects.filter(tenant_id=user_id).first()

            if not contract:
                return Response({
                    'code': 404,
                    'msg': '未找到相关合同'
                }, status=404)

            # 检查权限：只有合同的租客或房东可以查看合同
            if request.user.id not in [contract.tenant_id, contract.landlord_id]:
                return Response({
                    'code': 403,
                    'msg': '您没有权限查看此合同'
                }, status=403)

            serializer = ContractSerializer(contract)

            return Response({
                'code': 200,
                'msg': '合同获取成功',
                'data': serializer.data
            })
        except ValueError:
            return Response({
                'code': 400,
                'msg': '参数格式错误'
            }, status=400)
        except Exception as e:
            return Response({
                'code': 500,
                'msg': f'获取合同失败: {str(e)}'
            }, status=500)


import pika
class OrderCreateView(APIView):
    authentication_classes = [MyAuthentication]
    def post(self, request):
        order_data = {
            "orderno": f"{int(random.random() * 1000000000)}",
            "house_id": request.data.get("house"),
            "user_id": request.data.get("user"),
        }

        try:
            # 从Django设置获取RabbitMQ配置
            rabbitmq_conf = settings.RABBITMQ_CONFIG

            connection = pika.BlockingConnection(
                pika.ConnectionParameters(
                    host=rabbitmq_conf['HOST'],
                    port=rabbitmq_conf['PORT'],
                    credentials=pika.PlainCredentials(
                        username=rabbitmq_conf['USERNAME'],
                        password=rabbitmq_conf['PASSWORD']
                    )
                )
            )
            channel = connection.channel()
            channel.queue_declare(queue=rabbitmq_conf['QUEUE'], durable=True)

            channel.basic_publish(
                exchange='',
                routing_key=rabbitmq_conf['QUEUE'],
                body=json.dumps(order_data),
                properties=pika.BasicProperties(
                    delivery_mode=2,
                )
            )

            connection.close()
            return Response({"message": "订单已提交处理"}, status=201)

        except Exception as e:
            return Response({"error": f"订单处理失败: {str(e)}"}, status=500)


from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework import status


class HouseListingAPIView(APIView):
    """
    房产交易记录API视图，支持community字段的模糊和精确查询
    """

    def get(self, request, format=None):
        # 获取查询参数
        community = request.query_params.get('community', None)
        exact = request.query_params.get('exact', 'false').lower() == 'true'

        # 构建基础查询集
        queryset = HouseTransaction.objects.all()

        # 根据community参数进行筛选
        if community is not None:
            if exact:
                # 精确查询
                queryset = queryset.filter(community=community)
            else:
                # 模糊查询（不区分大小写）
                queryset = queryset.filter(community__icontains=community)

        # 序列化数据并返回
        serializer = HouseTransactionSerializer(queryset, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        # 处理创建新记录的请求
        serializer = HouseTransactionSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class HouseDetailAPIView(APIView):
    """
    单个房产交易记录的详细信息视图
    """

    def get_object(self, pk):
        return get_object_or_404(HouseTransaction, pk=pk)

    def get(self, request, pk, format=None):
        house = self.get_object(pk)
        serializer = HouseTransactionSerializer(house)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        house = self.get_object(pk)
        serializer = HouseTransactionSerializer(house, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        house = self.get_object(pk)
        house.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


import pika
from django.http import JsonResponse
from rest_framework.views import APIView


class OrderCreateView(APIView):
    def post(self, request):
        # 假设订单信息在请求的 JSON 数据中
        order_data = request.data

        try:
            # 连接到 RabbitMQ 服务器
            connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
            channel = connection.channel()

            # 声明一个队列
            channel.queue_declare(queue='order_queue')

            # 发送订单信息到队列
            channel.basic_publish(exchange='',
                                  routing_key='order_queue',
                                  body=str(order_data))

            # 关闭连接
            connection.close()

            return JsonResponse({'message': '订单请求已接收，正在处理中'}, status=200)
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)





# from rest_framework.views import APIView
# from rest_framework.response import Response
import pymongo
# from bson import ObjectId
# import json

# 假设你已经配置好 MongoDB 连接（根据实际情况替换）
mongo_client = pymongo.MongoClient(
    host="47.111.13.97",
    port=27017,
    username="admin",
    password="123456"
)
mongo_db = mongo_client["shuangji666"]


class OrderStatusView(APIView):
    # 改为 POST 方法（或 GET，根据前端调用方式选）
    def post(self, request):
        # 操作示例：插入一条数据到集合（表）test_collection
        collection = mongo_db["test_collection"]
        data = {"name": "示例数据", "info": "测试 MongoDB 连接"}
        result = collection.insert_one(data)

        # 查询刚插入的数据
        query_result = collection.find_one({"_id": result.inserted_id})

        # ObjectId 无法直接序列化为 JSON，需要处理
        query_result["_id"] = str(query_result["_id"])

        return Response({
            "inserted_id": query_result["_id"],
            "data": query_result
        })



class CreateCollectionView(APIView):
    def post(self, request):
        # 从请求参数中获取集合名称，默认为 "new_collection"
        collection_name = request.data.get('collection_name', 'news')

        try:

            my_db = mongo_client["my_db2"]
            # 创建集合
            my_collection = my_db["comment"]

            # 添加一个文档   需要指定数据
            document = {"userid": 1, "goodsid": 1, "message": "234423safdsfasf", 'types': '好评', 'pid': 0}
            ret = my_collection.insert_one(document)

            return Response({
                'status': 'success',
                'message': f'集合 "{collection_name}" 创建成功',
                'collections': mongo_db.list_collection_names()
            })

        except pymongo.errors.CollectionInvalid:
            # 集合已存在的情况
            return Response({
                'status': 'warning',
                'message': f'集合 "{collection_name}" 已存在',
                'collections': mongo_db.list_collection_names()
            })

        except Exception as e:
            # 其他错误处理
            return Response({
                'status': 'error',
                'message': f'创建集合失败: {str(e)}'
            }, status=500)


# 指定数据库为my_db2
mongo_db = mongo_client["my_db2"]


class DeleteCollectionView(APIView):
    def post(self, request):
        # 从请求参数中获取集合名称，默认为空
        collection_name = request.data.get('collection_name', 'my_db2')

        if not collection_name:
            return Response({
                'status': 'error',
                'message': '请提供集合名称'
            }, status=400)

        try:
            # 获取指定集合
            collection = mongo_db[collection_name]

            # 指定要删除的条件（必要条件）
            query = {"name": "小明", "title": "12"}

            # 执行删除操作
            result = collection.delete_many(query)

            return Response({
                'status': 'success',
                'message': f'成功删除 {result.deleted_count} 条数据',
                'deleted_count': result.deleted_count
            })
        except Exception as e:
            # 其他错误处理
            return Response({
                'status': 'error',
                'message': f'删除数据失败: {str(e)}'
            }, status=500)


from rest_framework.views import APIView
from rest_framework.response import Response
import pymongo

# MongoDB 连接配置（使用你的阿里云服务器信息）
mongo_client = pymongo.MongoClient(
    host="116.62.214.253",
    port=27017,
    username="admin",
    password="123456"
)
# mongo_db = mongo_client["my_db2"]  # 使用你指定的数据库名


class UpdateCollectionView(APIView):
    def post(self, request):
        # 获取必要参数
        collection_name = request.data.get('collection_name')
        query = request.data.get('query', {"name": "小明", "title": "12"})  # 查询条件
        update = request.data.get('update', {"name":"小泽","title":"15"})  # 更新内容

        # 验证必填参数
        if not collection_name:
            return Response({
                'status': 'error',
                'message': '请提供集合名称'
            }, status=400)

        if not query or not update:
            return Response({
                'status': 'error',
                'message': '查询条件和更新内容均为必填项'
            }, status=400)

        # 检查集合是否存在
        if collection_name not in mongo_db.list_collection_names():
            return Response({
                'status': 'error',
                'message': f'集合 "{collection_name}" 不存在'
            }, status=404)

        try:
            # 获取集合
            collection = mongo_db[collection_name]

            # 执行更新操作（默认更新所有匹配文档）
            result = collection.update_many(
                filter=query,
                update={"$set": update},  # 使用 $set 操作符更新指定字段
                upsert=False  # 不创建不存在的文档
            )

            # 返回更新结果
            return Response({
                'status': 'success',
                'message': f'更新完成',
                'matched_count': result.matched_count,  # 匹配的文档数
                'modified_count': result.modified_count,  # 实际修改的文档数
                'upserted_id': str(result.upserted_id) if result.upserted_id else None  # 插入的ID（如果有）
            })

        except Exception as e:
            # 其他错误处理
            return Response({
                'status': 'error',
                'message': f'更新数据失败: {str(e)}'
            }, status=500)


from rest_framework.views import APIView
from rest_framework.response import Response
import pymongo

# MongoDB 连接配置
mongo_client = pymongo.MongoClient(
    host="116.62.214.253",
    port=27017,
    username="admin",
    password="123456"
)
# mongo_db = mongo_client["my_db2"]


class FindCollectionView(APIView):
    def post(self, request):
        # 获取请求参数
        collection_name = request.data.get('collection_name')
        name = request.data.get('name')  # 新增：name 搜索字段
        title = request.data.get('title')  # 新增：title 搜索字段
        exact = request.data.get('exact', False)  # 是否精确匹配，默认模糊搜索
        sort_by = request.data.get('sort_by', 'name')  # 排序字段，默认 name
        sort_order = request.data.get('sort_order', 1)  # 排序方向，1=升序，-1=降序
        page = int(request.data.get('page', 1))
        page_size = int(request.data.get('page_size', 10))

        # 验证必要参数
        if not collection_name:
            return Response({
                'status': 'error',
                'message': '请提供集合名称'
            }, status=400)

        # 检查集合是否存在
        if collection_name not in mongo_db.list_collection_names():
            return Response({
                'status': 'error',
                'message': f'集合 "{collection_name}" 不存在'
            }, status=404)

        try:
            # 构建查询条件
            query = {}
            if name:
                query["name"] = name if exact else {"$regex": name, "$options": "i"}

            if title:
                query["title"] = title if exact else {"$regex": title, "$options": "i"}

            # 获取集合
            collection = mongo_db[collection_name]

            # 执行查询
            cursor = collection.find(
                query,
                {"name": 1, "title": 1, "_id": 1}  # 只返回 name 和 title 字段
            ).sort(sort_by, sort_order).skip((page - 1) * page_size).limit(page_size)

            # 转换结果为列表
            results = list(cursor)

            # 处理 ObjectId
            for doc in results:
                doc["_id"] = str(doc["_id"])

            return Response({
                'status': 'success',
                'message': '查询成功',
                'total_count': collection.count_documents(query),  # 总匹配数
                'page': page,
                'page_size': page_size,
                'data': results
            })

        except Exception as e:
            return Response({
                'status': 'error',
                'message': f'查询失败: {str(e)}'
            }, status=500)


# from rest_framework.views import APIView
# from rest_framework.response import Response
from pymongo import MongoClient
from bson import ObjectId
import datetime


class MovieCommentAPI(APIView):
    def get(self, request, movie_id=None):
        # MongoDB配置 - 使用与爬虫相同的配置
        MONGO_HOST = "47.111.13.97"
        MONGO_PORT = 27017
        MONGO_USER = "admin"
        MONGO_PASSWORD = "123456"
        MONGO_DB = "admin"
        MONGO_COLLECTION = "comments"

        try:
            # 连接MongoDB
            client = MongoClient(
                host=MONGO_HOST,
                port=MONGO_PORT,
                username=MONGO_USER,
                password=MONGO_PASSWORD,
                authSource="admin"
            )

            # 选择数据库和集合
            db = client[MONGO_DB]
            collection = db[MONGO_COLLECTION]

            # 查询所有type=好评的评论
            query = {"type": "好评"}
            # 如果传了movie_id，则加上movie_id过滤
            if movie_id:
                query["movie_id"] = movie_id

            # 分页参数
            page = int(request.query_params.get('page', 1))
            page_size = int(request.query_params.get('page_size', 10))
            skip = (page - 1) * page_size

            total_count = collection.count_documents(query)

            # 查询评论，按时间倒序，分页
            comments = list(collection.find(
                query,
                {"_id": 0, "id": 1, "username": 1, "content": 1, "rating": 1, "time": 1, "type": 1, "is_fake": 1, "movie_id": 1}
            ).sort("time", -1).skip(skip).limit(page_size))

            # 格式化时间
            for comment in comments:
                if isinstance(comment["time"], str):
                    try:
                        comment["time"] = datetime.datetime.strptime(comment["time"], "%Y-%m-%d %H:%M").strftime("%Y-%m-%d %H:%M")
                    except ValueError:
                        pass
                elif isinstance(comment["time"], datetime.datetime):
                    comment["time"] = comment["time"].strftime("%Y-%m-%d %H:%M")

            return Response({
                "success": True,
                "data": comments,
                "total": total_count,
                "page": page,
                "page_size": page_size
            })

        except Exception as e:
            return Response({
                "success": False,
                "error": str(e)
            }, status=500)

        finally:
            if 'client' in locals():
                client.close()













